#pragma once
#ifndef _CALL_GRAPH_H_
#define _CALL_GRAPH_H_ 1

#include <vector>
#include <stack>
#include "SDCF.h"
#include "CFG.h"
using namespace std;

#define MAX_FUNCTION_NAME 128

struct function_node;

struct function_node{
	unsigned int entrance_address;
	vector<function_node*> calleeList;
	function_node* caller;
	unsigned int expected_return_address;
	char function_name[MAX_FUNCTION_NAME];
	file_t file_function_cfg;
	CFG *cfg;
	int deep;
	int breadth;
};

class CallGraph{
private:
	function_node *headFunction;
	vector<function_node*> functionList;
	int size;
public:
	function_node *current_func_node;
	CallGraph();
	~CallGraph();

	/*
	 * Set the entrance function of the call graph
	 */
	void setHeadFunction(function_node* entranceFunction);

	/*
	 * Return the entrance function of the call graph
	 */
	function_node* getHeadFunction();

	/*
	 * Create a new function node and add it to the call graph
	 */
	function_node* createFunctionNode(unsigned int entrance_address,
		unsigned int return_address, char *node_name);

	/*
	 * Add the callee function node to the callee list of
	 * the caller function
	 */
	bool addCallee(function_node *caller,function_node *callee);

	/*
	 * Return the caller function node of the callee
	 */
	function_node* getCaller(function_node *callee);

	/*
	 * Return the size of the function nodes in the call graph
	 */
	int getSize();

	/*
	 * Print the content of CFG for all function nodes in the call graph
	 */
	void printAllNode();

	/*
	 * Print the content of CFG for the function node
	 */
	void printSingleNode(function_node *current_node);
};

#endif